package com.hex.ds.hdrs.common.excel;

import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
import com.hex.bigdata.hbda.utils.StringUtils;
import com.hex.ds.hdrs.common.enums.ExcelImportOperationEnum;
import com.hex.ds.hdrs.cron.dto.CronTaskImportDto;
import com.hex.ds.hdrs.cron.po.CronTaskDef;
import com.hex.ds.hdrs.cron.service.CronTaskDefService;
import com.hex.ds.hdrs.period.job.dto.PeriodJobTaskDto;
import com.hex.ds.hdrs.period.job.po.PeriodJobDef;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.quartz.CronExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;

/**
 * @Package: com.hex.ds.hdrs.common.excel
 * @ClassName TalentImportVerifyHandler
 * @Description: 周期作业定义导入自定义校验
 * @Author: ji.tang
 * @Date 2023/2/28 11:08
 * @Version v1.0
 **/
@Data
@Component
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class CronTaskImportVerifyHandler implements IExcelVerifyHandler<CronTaskImportDto> {

    public String appCode;

    private final CronTaskDefService cronTaskDefService;

    private final ThreadLocal<List<CronTaskImportDto>> threadLocal = new ThreadLocal<>();

    /*
     * @Method: verifyHandler <br>
     * @Param: [cronTaskImportDto] <br>
     * @Return: cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult <br>
     * @Description：导入校验<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/3 11:46 <br>
     * @Version： V2.0.2<br>
     */
    @Override
    public ExcelVerifyHandlerResult verifyHandler(CronTaskImportDto cronTaskImportDto) {
        List<CronTaskImportDto> threadLocalVal = threadLocal.get();
        if (threadLocalVal == null) {
            threadLocalVal = new ArrayList<>();
        }
        StringJoiner joiner = new StringJoiner(",");

        // 任务编码Excel数据重复校验和DB数据库数据校验
        checkTaskCode(joiner, cronTaskImportDto, threadLocalVal);
        // 检验有限时间段
        checkIsValidDate(joiner, cronTaskImportDto);
        // 正则表达式校验
        checkCronExpress(joiner, cronTaskImportDto);
        threadLocalVal.add(cronTaskImportDto);
        threadLocal.set(threadLocalVal);
        if (joiner.length() != 0) {
            return new ExcelVerifyHandlerResult(false, joiner.toString());
        }
        return new ExcelVerifyHandlerResult(true);
    }

    /*
     * @Method: checkTaskCode <br>
     * @Param: [joiner, cronTaskImportDto, threadLocalVal] <br>
     * @Return: void <br>
     * @Description：任务编码校验<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/4 15:43 <br>
     * @Version： V2.0.2<br>
     */
    public void checkTaskCode(StringJoiner joiner, CronTaskImportDto cronTaskImportDto, List<CronTaskImportDto> threadLocalVal) {
        for (CronTaskImportDto haveCheckDto : threadLocalVal) {
            if (haveCheckDto.getTaskCode().equals(cronTaskImportDto.getTaskCode())) {
                joiner.add("[任务编码]" + cronTaskImportDto.getTaskCode() + "与第" + (haveCheckDto.getRowNum() + 1) + "行数据重复");
            }
        }
        CronTaskDef cronTaskDef = cronTaskDefService.queryByTaskCode(cronTaskImportDto.getTaskCode());
        if (cronTaskDef != null && !cronTaskDef.getAppCode().equals(appCode)){
            joiner.add("[任务编码]" + cronTaskDef.getTaskCode() + "已存在且不属于当前应用");
        }else if (ExcelImportOperationEnum.A.getName().equals(cronTaskImportDto.getOperation()) && cronTaskDef != null) {
            joiner.add("[任务编码]" + cronTaskImportDto.getTaskCode() + "已存在，不允许重复新增");
        } else if ((ExcelImportOperationEnum.U.getName().equals(cronTaskImportDto.getOperation())
                || ExcelImportOperationEnum.D.getName().equals(cronTaskImportDto.getOperation())) && cronTaskDef == null) {
            joiner.add("[任务编码]" + cronTaskImportDto.getTaskCode() + "不存在，不能更新或删除");
        }
    }

    /**
     * @Method: checkStartDate
     * @Param: [isValidDate, startDate]
     * @Return: java.lang.String
     * @Description: 开始时间校验
     * @Author: ji.tang
     * @Date: 2023/2/28 14:37
     * @Version: V1.0
     */
    public void checkIsValidDate(StringJoiner joiner, CronTaskImportDto cronTaskImportDto) {
        if ("1".equals(cronTaskImportDto.getIsValidDate()) &&
                (StringUtils.isBlank(cronTaskImportDto.getTaskStDate()) || StringUtils.isBlank(cronTaskImportDto.getTaskEndDate()))) {
            joiner.add("[有效时间段]该作业开启了有效时间限制，但开始时间或结束时间为空");
        }
    }

    /*
     * @Method: checkCronExpress <br>
     * @Param: [joiner, cronTaskImportDto] <br>
     * @Return: void <br>
     * @Description：Cron表达式校验<br>
     * @Author： wz.li<br>
     * @Date： 2023/4/4 15:39 <br>
     * @Version： V2.0.2<br>
     */
    public void checkCronExpress(StringJoiner joiner, CronTaskImportDto cronTaskImportDto){
        if (!CronExpression.isValidExpression(cronTaskImportDto.getCronExpress())) {
            joiner.add("[cron表达式]格式错误");
        }
    }
}
